#include <iostream>
using std::cout;
using std::endl;

class Point
{
public:
    Point(int x,int y)
    : _ix(x)
    , _iy(y)
    {
        cout << "Point(int,int)" << endl;
    }

    void print() const{
        cout << "(" << _ix
            << "," << _iy
            << ")" << endl;
    }

    ~Point(){
        cout << "~Point()" << endl;
    }
private:
    int _ix;
    int _iy;
};

template <class T>
class RAII
{
public:
    //1.在构造函数中初始化资源（托管资源）
    RAII(T * data)
    : _data(data)
    {
        cout << "RAII(T*)" << endl;
    }

    //2.在析构函数中释放资源
    ~RAII(){
        cout << "~RAII()" << endl;
        if(_data){
            delete _data;
            _data = nullptr;
        }
    }

    //3.提供若干访问资源的方法
    T * operator->(){
        return _data;
    }
    
    T & operator*(){
        return *_data;
    }

    T * get() const{
        return _data;
    }

    void set(T * data){
        if(_data){
            delete _data;
            _data = nullptr;
        }
        _data = data;
    }

    //4.不允许复制或赋值
    RAII(const RAII & rhs) = delete;
    RAII& operator=(const RAII & rhs) = delete;
private:
    T * _data;
};

void test0(){
    /* Point * pp = new Point(1,2); */
    /* pp->print(); */
    /* (*pp).print(); */

    //利用栈对象的生命周期结束时，会自动调用析构函数
    //完成资源清理
    RAII<int> raii(new int(1));

    //pt不是一个指针，而是一个对象，
    //但是它的使用已经和指针完全一致了
    //可以托管堆上的Point对象，而且不用考虑delete
    RAII<Point> pt(new Point(1,2));
    pt->print();
    /* pt.operator->()->print(); */
    (*pt).print();

}

int main(void){
    test0();
    return 0;
}
